package cn.com.coding.common.log;

import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 控制层切面输出日志
 *
 * @author mxz
 */
@Aspect
@Component
public class ControllerLogAspect {

    @Resource
    private HttpServletRequest request;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static String getLoginUserName() {
        return "Anonymous";
    }

    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    public void controller() {
    }

    @Before("controller()")
    public void writeBeforeLog(JoinPoint jp) {
        this.debugInController(jp, "Start");
    }

    @After("controller()")
    public void writeAfterLog(JoinPoint jp) {
        this.debugInController(jp, "End");
    }

    private void debugInController(JoinPoint jp, String msg) {
        String userName = getLoginUserName();
        String remoteClientIp = request.getRemoteAddr();
        String simpleUrl = request.getRequestURI();
//        logger.info("\n[{}] [{}] [{}] {}.{}() {} ",
//                remoteClientIp, simpleUrl, userName, jp.getTarget().getClass().getSimpleName(),
//                jp.getSignature().getName(), msg);
        logger.info("[{}] [{}] [{}] {}.{}() {} ", remoteClientIp, simpleUrl, userName, jp.getTarget().getClass().getSimpleName(), jp.getSignature().getName(), msg);
    }

    @Before("controller()")
    public void writeParams(JoinPoint jp) {
        String[] names = ((CodeSignature) jp.getSignature()).getParameterNames();
        Object[] args = jp.getArgs();

        if (ArrayUtils.isEmpty(names)) {
            return;
        }

        StringBuilder sb = new StringBuilder("Arguments: ");
        for (int i = 0; i < names.length; i++) {
            sb.append(names[i] + " = " + args[i] + ",");
        }

        debugInController(jp, sb.toString());
    }
}
